
#include <stdint.h>

// options to control how MicroPython is built

// Use the minimal starting configuration (disables all optional features).
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_CORE_FEATURES)

// You can disable the built-in MicroPython compiler by setting the following
// config option to 0.  If you do this then you won't get a REPL prompt, but you
// will still be able to execute pre-compiled scripts, compiled with mpy-cross.
#define MICROPY_ENABLE_COMPILER     (1)

#define MICROPY_QSTR_EXTRA_POOL           mp_qstr_frozen_const_pool
#define MICROPY_ENABLE_GC                 (1)
#define MICROPY_HELPER_REPL               (1)
#define MICROPY_MODULE_FROZEN_MPY         (0)
#define MICROPY_ENABLE_EXTERNAL_IMPORT    (1)
#define MICROPY_PY_BUILTINS_FLOAT         (1)
#define MICROPY_SCHEDULER_DEPTH            8

// micropython module(import micropython)
#define MICROPY_PY_MICROPYTHON_MEM_INFO         (1)
#define MICROPY_MEM_STATS                       (1)
#define MICROPY_MALLOC_USES_ALLOCATED_SIZE      1024
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF  (1)
#define MICROPY_ENABLE_PYSTACK                  (1)


#define MP_SSIZE_MAX                (0x7fffffff)  /* 整数最大值, 32位 */
#define MICROPY_LONGINT_IMPL        (MICROPY_LONGINT_IMPL_MPZ)
#define MICROPY_FLOAT_IMPL          (MICROPY_FLOAT_IMPL_FLOAT)

//#define MICROPY_MALLOC_USES_ALLOCATED_SIZE      (1)  /**/

// Fine control over Python builtins, classes, modules, etc.
#define MICROPY_PY_ASYNC_AWAIT                  (0)
#define MICROPY_PY_BUILTINS_SET                 (1) 
#define MICROPY_PY_ATTRTUPLE                    (1)
#define MICROPY_PY_COLLECTIONS                  (1)
#define MICROPY_PY_MATH                         (1)
#define MICROPY_PY_STRUCT                       (1)
#define MICROPY_PY_BUILTINS_HELP                (1)

// https://docs.singtown.com/micropython/zh/latest/openmvcam/reference/isr_rules.html
#define MICROPY_ENABLE_SCHEDULER                (1)   /* call MICROPY_EVENT_POLL_HOOK when in delay and busy wait case to handle schedule task */
#define MICROPY_KBD_EXCEPTION                   (1)   /* keyboard interrupt, mp_hal_set_interrupt_char */
#define MICROPY_ENABLE_FINALISER                (1)
//#define MICROPY_STACK_CHECK                     (1)

#define MICROPY_ALLOC_PATH_MAX              (128)
#define MICROPY_ALLOC_PARSE_CHUNK_INIT      (16)
#define MICROPY_HEAP_SIZE                   (96*1024)

// sys
#define MICROPY_PY_SYS_GETSIZEOF            (1)
#define MICROPY_PY_SYS_MAXSIZE              (1)
#define MICROPY_PY_SYS_MODULES              (1)
#define MICROPY_PY_SYS_EXIT                 (1)
#define MICROPY_PY_IO                       (1)
#define MICROPY_PY_SYS_STDFILES             (1)
#define MICROPY_PY_SYS_STDIO_BUFFER         (1)

// uos, file system
#define MICROPY_VFS                         (1)
#define MICROPY_VFS_LFS2                    (1)
#define MICROPY_READER_VFS                  (1)
#define MICROPY_PY_IO_FILEIO                (1)

// extended modules
#define MICROPY_PY_UCTYPES          (1)
#define MICROPY_PY_UZLIB            (1)
#define MICROPY_PY_UJSON            (1)
#define MICROPY_PY_URE              (1)
#define MICROPY_PY_ARRAY            (1)


// bsp modules, machine, uctypes, etc.
#define MICROPY_PY_MACHINE                  (1)
#define MICROPY_PY_UTIME_MP_HAL             (1)  /* modutime.c: https://blog.csdn.net/suyong_yq/article/details/119879649 */

// spi interface
#define MICROPY_PY_MACHINE_SOFTSPI          (1)
#define MICROPY_PY_MACHINE_SPI              (1)
 
#define MICROPY_PY_MACHINE_SPI_MSB  SPI_BIGENDIAN
#define MICROPY_PY_MACHINE_SPI_LSB  SPI_LITTLEENDIAN

// extend modules
//#ifndef MICROPY_PY_UOS
//#define MICROPY_PY_UOS                      (1)
//#endif
//#define MICROPY_PY_OS_DUPTERM       (3)
//#define MICROPY_PY_UOS_DUPTERM_BUILTIN_STREAM (1)


// type definitions for the specific machine

typedef intptr_t mp_int_t; // must be pointer size
typedef uintptr_t mp_uint_t; // must be pointer size
typedef long mp_off_t;

// extra built in names to add to the global namespace
extern const struct _mp_obj_module_t mp_module_machine;
extern const struct _mp_obj_module_t mp_module_utime;
extern const struct _mp_obj_module_t uos_module;

// stat、open内置函数由VFS提供的API实现
#define mp_import_stat mp_vfs_import_stat
#define mp_builtin_open mp_vfs_open
#define mp_builtin_open_obj mp_vfs_open_obj

#if MICROPY_VFS_LFS2 > 0
#define mp_type_fileio mp_type_vfs_lfs2_fileio
#define mp_type_textio mp_type_vfs_lfs2_textio
#else
#define mp_type_fileio mp_type_vfs_lfs1_fileio
#define mp_type_textio mp_type_vfs_lfs1_textio
#endif

// 模块放入mp_module_builtins_globals_table表, 已经加载完毕
#define MICROPY_PORT_BUILTINS \
    { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mp_builtin_open_obj) },


// 模块放入mp_builtin_module_table表, 需要手动import
#define MICROPY_PORT_BUILTIN_MODULES                                  \
    { MP_ROM_QSTR(MP_QSTR_machine), MP_ROM_PTR(&mp_module_machine) }, \
	{ MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&mp_module_utime) },     \
	{ MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&uos_module) }, 


// We need to provide a declaration/definition of alloca()
#include <alloca.h>


// 添加x804架构描述文件, W806板级描述文件(配置硬件参数、硬件模块)
#include <mpxt804.h>
#include <mpxt804_board.h>

// py/mpstate.h: #define MP_STATE_VM(x) (mp_state_ctx.vm.x)
// vm是个结构体, 在MICROPY_PORT_ROOT_POINTERS宏里的参数都会定义在vm结构体内
#define MP_STATE_PORT MP_STATE_VM

#define MICROPY_PORT_ROOT_POINTERS                                        \
    const char *readline_hist[8];                                         \
	mp_obj_t pyb_config_main;                                             \
    struct _pyb_uart_obj_t *pyb_stdio_uart;                               \
    struct _pyb_uart_obj_t* pyb_uart_obj_all[MICROPY_HW_MAX_UART_CNT];    \
    struct _machine_timer_obj_t* timer_obj_all[MICROPY_HW_MAX_TIMER_CNT]; \
    struct _machine_pwm_obj_t* pwm_obj;                                   \
    struct _machine_rtc_obj_t* rtc_obj;                                   \
    struct _machine_pin_obj_t* pin_obj_all[48]; /* PA-16, PB-32Pin */     \
    struct _machine_hard_spi_obj_t* spi_obj;


#if MICROPY_PY_THREAD                         /* 还不支持thread */
#define MICROPY_EVENT_POLL_HOOK \
    do { \
        extern void mp_handle_pending(bool raise_exc); \
        mp_handle_pending(true); \
        if (pyb_thread_enabled) { \
            MP_THREAD_GIL_EXIT(); \
            pyb_thread_yield(); \
            MP_THREAD_GIL_ENTER(); \
        } else { \
            __WFI(); \
        } \
    } while (0);

#define MICROPY_THREAD_YIELD() pyb_thread_yield()
#else
#define MICROPY_EVENT_POLL_HOOK \
    do { \
        extern void mp_handle_pending(bool raise_exc); \
        mp_handle_pending(true); \
    } while (0);

#define MICROPY_THREAD_YIELD()
#endif

